<template>
    <div class="center_layout">
        <div class="list">
            <MESSAGE v-show="current_model=== 'message'"  
            v-model:current_chat="current_chat"
            v-model:current_chatlist="current_chatlist"
           >
            </MESSAGE>
            <FRIENDS 
                    v-show="current_model==='friends'" 
                    v-mdoel:current_model="current_model" 
            >
            </FRIENDS>
            <GROUPS v-show="current_model==='group'"
                    v-mdoel:current_model="current_model" 
                    >
            </GROUPS>
            <TRANSACTION v-show="current_model=='transaction'">
            </TRANSACTION>
            <SETTING v-show="current_model=='setting'">   
            </SETTING>
        </div>
        <div id="chat_window">
            <WINDOW 
             v-model:current_chat="current_chat"
             v-mdoel:current_model="current_model"
             v-model:message_cache="message_cache"
             v-model:message_data="message_data"
             v-model:users_info_cache="users_info_cache"
            ></WINDOW>
        </div>
        <div class="show_info_box" v-if="room_show_info!=null">
            <SHOWALLINFO/>
        </div>
    </div>
</template>

<script setup>
import MESSAGE from './message/layout.vue'
import WINDOW from './window/layout.vue'
import FRIENDS from "./friends_list/layout.vue"
import GROUPS from "./group_list/layout.vue"
import TRANSACTION from "./transactions/layout.vue"
import SETTING from "./setting/layout.vue"
import SHOWALLINFO from "./commshowinfo.vue"
import { ref, inject, onMounted, watch, onBeforeMount, reactive, onUnmounted, computed } from 'vue'
import { fetch_double_all, fetch_group_all } from "@/api/chat/message.js"
import { flush_room_stream} from "@/api/chat/room.js"
const room_show_info = computed(() => {
    return chat.value.get_current_show_info_room_info() || null
})
const last_stream_cache = ref({})
const chat_cache = inject('chat_cache')
const room_stream=inject('room_stream')
const message_cache = ref({})
const message_data = ref([])
const users_info_cache = reactive({})
const users_infoCache = inject('users_info_cache')
// 当前选中的模块
const user = inject('user')()
const chat = inject('chat')()
let current_model = defineModel('current_model',
    {
        default: 'message',
        type: String
    }
)
watch(()=>message_cache.value,async (newValue, oldValue) => { 
    Object.keys(newValue).forEach(async (item) => {
            // console.log(item)
    })
    
}, {deep:true})

// 当前可会话信息
let current_chatlist = ref([])
let userid = ref(null)
const timer = ref({})


const add_message_list = (data) => {
    // 将消息添加到消息列表中
    // 如果当前消息列表中存在该消息对象,则不添加
    // data:data，limit,meta:{room_id,stream_time，type:friend/group}
    let room_info;
    if (data.meta.type === 'double') {
        room_info = chat.value.get_friend_info_by_room_id(data.meta.room_id)
    }
    if (data.meta.type === 'group') {
        room_info = chat.value.get_group_info_by_room_id(data.meta.room_id)
    }
    // 由于架构问题,不做大量修改,沿用
    chat.value.add_current_chat_list(data.meta.room_id, room_info)
    current_chatlist.value[data.meta.room_id]=room_info
}


watch(()=> current_model.value, (newvalue,oldValue) => {
    // console.log(newvalue)
})

// 当前选中的聊天标记,采用房间号进行标记,但实际逻辑处理用的是仓库
// let current_chat = ref(null)
// 由于架构问题,采用中间Computed
let middle_current_chat = computed(() => chat.value.get_current_chat())
watch(() => middle_current_chat.value, (newValue, oldValue) => { 
    current_chat.value=newValue
})
let current_chat =ref(null)
watch(() => current_chat.value,async (newValue, oldValue) => {
    if (!newValue || newValue.room_id === oldValue?.room_id) return
    // console.log(current_chat.value)
    // 在此处更新,方便管理
    if (newValue != null) {  
         if (newValue.type == 'double') {
        // 这样做只是为了同一形式,实际直接就可以获取,主要是为了群聊的信息管理
        const friend_id = chat.value.get_friend_info_by_room_id(newValue.room_id)?.friend_info?.id
        let data;
        // 对于私聊没有必要存储房间id
        if (!users_info_cache?.[friend_id]) {
            data = await users_infoCache.getData(friend_id)
            if (data) {
                users_info_cache[friend_id] = data
            } else {
                // 从服务器获取数据
                let server_data = await get_user_by_id(friend_id)
                if (server_data) {
                    server_data['user_id'] = server_data?.id
                    delete server_data['id']
                    users_info_cache[friend_id] = server_data
                    users_infoCache.putData({ ...server_data, room_id: newValue.room_id })
                }
            }
            // console.log(users_info_cache[friend_id])
        }
    }
    if (newValue.type == 'group') {
        //直接获取所有的信息
        if (!users_info_cache?.[newValue.room_id]) {
            // 认为没有存储,先从缓存获取
            const data = await users_infoCache.getAllDataByIndex('room_id', newValue.room_id)
            if (data.length > 0) {
                users_info_cache[newValue.room_id]=data
            }
        }
    }
    }
})

// 将级别分为二级,用于减少开销
const first_level = reactive({
    friends: {},
    groups: {}
})
const second_level = reactive({
    friends: {},
    groups: {}
})

const deal_fetch_room_info = (room_id, type, newstream_time) => {
  // 解决?.的赋值问题
  if (type === 'double') {
    if (first_level.friends?.[room_id]) {
      first_level.friends[room_id].stream_time = newstream_time;
    }
    if (second_level.friends?.[room_id]) {
      second_level.friends[room_id].stream_time = newstream_time;
    }
  }
  else if (type === 'group') {
    if (first_level.groups?.[room_id]) {
      first_level.groups[room_id].stream_time = newstream_time;
    }
    if (second_level.groups?.[room_id]) {
      second_level.groups[room_id].stream_time = newstream_time;
    }
  }
};

const deal_change_level_to_Two= async (data, type) => {
    // 首先处理,stream流的信息
    // 如果多次返回为空就,降级,并处理更新stream流,更新消息数据
    // data将返limit字段,0/1用来处理是否空数据
    //room:friend_info，room_info，room_stream
    // data:data，limit,meta:{room_id,stream_time，type:friend/group}

    if (type == "friend") {    
        data.forEach((item) => {
          
            first_level.friends[item.meta.room_id].limit += item.limit
            if (first_level.friends[item.meta.room_id].limit == 3) { 
                second_level.friends[item.meta.room_id] = first_level.friends[item.meta.room_id]
                delete first_level.friends[item.meta.room_id]
            }
            deal_update_message_and_info(item)
        })
    }
    if (type == "groups") { 
        data.forEach((item) => {
            first_level.groups[item.meta.room_id].limit += item.limit
            if (first_level.groups[item.meta.room_id].limit == 3) { 
                            second_level.groups[item.meta.room_id] = first_level.groups[item.meta.room_id]
                            delete first_level.groups[item.meta.room_id]
                        }

            deal_update_message_and_info(item)
        })
    }
}
const deal_change_level_to_One = async (data, type) => {
    // 将二级升级到一级
     // 首先处理,stream流的信息
    // 只要有消息,就升级,并处理更新stream流,更新消息数据
    // data将返limit字段,0/1用来处理是否空数据
    //rom:friend_info，room_info，room_stream
    // data:data，limit,meta:{room_id,stream_time，type:friend/group}
    if (type == "friend") {    
        data.forEach((item) => { 
           
            if (item.data.length > 0) {
                first_level.friends[item.meta.room_id]= second_level.friends[item.meta.room_id]
                delete second_level.friends[item.meta.room_id]
            }
             deal_update_message_and_info(item,)
        })
    }

    if (type == "group") { 
        data.forEach((item) => { 
             if (item.data.length > 0) {
                first_level.groups[item.meta.room_id]= second_level.groups[item.meta.room_id]
                delete second_level.groups[item.meta.room_id]
            }
             deal_update_message_and_info(item)
        })
    }
}

const deal_update_message_and_info = async (server_data) => {
    deal_fetch_room_info(server_data.meta.room_id,server_data.meta.type,server_data.meta.stream_time)
    const new_messages = server_data?.data || []
    try {
        if (new_messages.length > 0) {
            // 存在消息判断是否需要将消息信息加入到列表
           
            // 合并消息，避免重复
            const existing_messages = message_cache.value[server_data.meta.room_id] || []
            const unique_new_messages = new_messages.filter(new_msg =>
                !existing_messages.some(existing_msg =>
                    existing_msg.messages_id === new_msg.messages_id
                )
            )
            if (unique_new_messages.length > 0) {
                const updated_messages = [...existing_messages, ...unique_new_messages]
                add_message_list(server_data)
                // 更新内存缓存
                message_cache.value[server_data.meta.room_id] = updated_messages
                message_data.value = [...updated_messages]
                // 更新IndexedDB缓存
                await chat_cache.putAllData(unique_new_messages)

                // 更新stream时间
                const new_stream_time = server_data['meta']['stream_time']
                // 若无更新返回的是0,主要是为了处理群组和个人的方案,同时更新缓存中的流信息
                // 采用单批次,提高及时性
              
                if (new_stream_time) {
                    // 如果消息是当前聊天就,设置为0未读量
                    const middle_stream = await room_stream.getData(server_data.meta.room_id)
                    await flush_room_stream(server_data.meta.room_id, userid.value, new_stream_time)
                    await room_stream.putData({
                        room_id: server_data.meta.room_id,
                        stream_time: new_stream_time,
                        unread:
                            chat.value?.get_current_chat()?.room_id == server_data.meta.room_id
                                ? 0 : ((middle_stream?.unread || 0) +
                                    unique_new_messages[unique_new_messages.length - 1])
                        ,
                        last_message: unique_new_messages[unique_new_messages.length-1]
                    })
                    last_stream_cache.value[server_data.meta.room_id] = new_stream_time
                }
            }
        }
    } catch (error) {
        console.error('Error fetching messages:', error)
    }
}

watch((second_level), async (newvalue, oldvalue) => {
    timer.value['friend_level_two'] = null
    timer.value['group_level_two'] = null
    if (Object.keys(newvalue.friends).length > 0) {
        timer.value['friend_level_two'] = setInterval(async () => {
            if (Object.keys(second_level['friends']).length == 0) return
            const data = await fetch_double_all(second_level['friends'], userid.value)
            deal_change_level_to_One(data, 'friend')
        }
            , 10000)
    
    }

if (Object.keys(newvalue.groups).length > 0) {
        timer.value['group_level_two'] = setInterval(async () => {
            if (Object.keys(second_level['groups']).length == 0) return
            const data = await fetch_double_all(second_level['groups'], userid.value)
            deal_change_level_to_One(data, 'group')
        }
            , 10000)
    
    }
})

const deal_add_streaminfo =(stream, room) => {
    let middledata = {}
    if (stream?.length > 0) {
        stream.forEach((item) => {
            if (room?.[item.room_id]) {
                middledata[item.room_id] = {
                    ...room[item.room_id]
                    , stream_time: item.stream_time
                    , limit: 0
                }
            }
        })
    } else { 
        const roomids = Object.keys(room)
        roomids.forEach(item => {
            middledata[item] = {
                    ...room[item]
                    , stream_time: 1
                    , limit: 0
                }
        })
    }
    return middledata
};

const get_all_frineds_message = async (time = 5000) => {
    if (timer.value['friend_level_one']) { 
        clearInterval(timer.value['friend_level_one'])
    }

    if (Object.keys(first_level['friends']).length > 0) {
        const Room_Stream = await room_stream.getAllData()
        const newroom_info = deal_add_streaminfo(Room_Stream, first_level['friends'])
        first_level['friends'] = newroom_info
        timer.value['friend_level_one'] = setInterval(async () => {
            if (Object.keys(first_level['friends']).length ==0) return 
            const data = await fetch_double_all(first_level['friends'], userid.value)
            await deal_change_level_to_Two(data, 'friend')
    }, time)
    }
}

const get_all_groups_message = async (time = 5000) => { 
     if (timer.value['group_level_one']) { 
        clearInterval(timer.value['group_level_one'])
    }

    if (Object.keys(first_level['groups']).length > 0) {
        const Room_Stream = await room_stream.getAllData()
        const newroom_info = deal_add_streaminfo(Room_Stream, first_level['groups'])
        first_level['groups']= newroom_info
        timer.value['group_level_one'] = setInterval(async () => { 
             if (Object.keys(first_level['groups']).length ==0) return 
            const data = await fetch_group_all(first_level['groups'],userid.value)
            await deal_change_level_to_Two(data, 'group')
    }, time)

    }
}

const clear_route_cache = async() => { 
    // 用于每次启动检索,非法的数据如删除后的房间信息等。
    
}

onBeforeMount(() => { 
    userid.value = user?.value?.get_user()?.id
})

onMounted(async () => {

    //采用浏览器本地持久化,操作。暂时采用浏览器的持久化，可更新为indexDB或者本地文件
    current_chatlist.value = chat.value.get_current_chat_list()
    // 在此处开启所有轮询.采用空惩罚机制
    const groups=chat.value.get_group_list()
    const friends = chat.value.get_friend_list()
    // 在这里格式化数据类型
    friends.forEach((item) => {
        first_level.friends[item.room_info.room_id] =item
    })
    groups.forEach((item) => {
        first_level.groups[item.room_info.room_id] = item
    })
    // 初次轮询
    await get_all_frineds_message()
    await get_all_groups_message()
})
onUnmounted(() => {
    // 清除定时器
    timer.value={}
})

</script>

<style scoped>
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.center_layout {
    width: 100%;
    height: 100%;
    display: flex;
    gap: 10px; /* 使用 gap 替代 margin 来控制间距 */
}

.list {
    flex: 0 0 20%; /* 固定宽度 20% */
    height: 100%;
    min-width: 150px; /* 防止内容溢出 */
}

.list::-webkit-scrollbar {
    display: none;
}

#chat_window {
    border-radius: 8px;
    flex: 1; 
    height: 100%;
    background:linear-gradient(135deg, #a7e9c8, #8cb0ee);
}
.show_info_box{
    position:fixed;
    top:80px;
    left: 50%;
    transform: translateX(-50%);
}
</style>